//
//  RecvAndSendPacketTool.m
//  Fotile
//
//  Created by AllenKwok on 16/5/30.
//  Copyright © 2016年 xlink.cn. All rights reserved.
//  设备IOS SDK接收发送数据类

#import "RecvAndSendPacketTool.h"
//#import "SterilizerModel.h"
//#import "CookerModel.h"

//#import "FTIKCCHomeDeviceManager.h"
#import "FTSmartDeviceModule.h"

#define PACKETHEAD  (0xf4f5)
#define PACKETHEADFIRST  (0xf4)

@interface RecvAndSendPacketTool ()

@property (nonatomic,strong) NSMutableDictionary *sendDeviceDataArrDict;

@end

@implementation RecvAndSendPacketTool{
    NSMutableArray  *_recvDeviceDataArr;
    NSThread        *_recvThread;
    NSLock  *_lock;
}

+ (instancetype)share{
    static RecvAndSendPacketTool *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[RecvAndSendPacketTool alloc] init];
        instance->_lock = [[NSLock alloc] init];
    });
    return instance;
}

- (void)recvData:(NSData *)data withDevice:(XLDeviceEntity *)device{
    
    [self handleDeviceData:data withDevice:device];
}
- (void)handleDeviceData:(NSData *)deviceData withDevice:(XLDeviceEntity *)device {
    if (!_recvThread) {
        _recvThread = [[NSThread alloc] initWithTarget:self selector:@selector(breakUpPacketThread) object:nil];
        [_recvThread start];
    }
    if (!_recvDeviceDataArr) {
        _recvDeviceDataArr = [NSMutableArray array];
    }
    NSString *address = [device getMacAddressSimple];
    NSDictionary *oldDataDic = nil;
    for (NSUInteger i = 0; i < _recvDeviceDataArr.count; i++) {
        NSDictionary *dic = _recvDeviceDataArr[i];
        XLDeviceEntity *temp = [dic objectForKey:@"device"];
        if ([address isEqualToString:[temp getMacAddressSimple]]) {
            oldDataDic = dic;
            break;
        }
    }
    if (!oldDataDic) {
        oldDataDic = @{@"device" : device, @"data" : [NSMutableData data]};
        [_recvDeviceDataArr addObject:oldDataDic];
    }
    NSMutableData *oldData = [oldDataDic objectForKey:@"data"];
    
    [oldData performSelector:@selector(appendData:) onThread:_recvThread withObject:deviceData waitUntilDone:YES];
}
- (void)breakUpPacketThread{
    
    FTLog(@"Recv Data Thread Start");
    
    [NSTimer scheduledTimerWithTimeInterval:[[NSDate distantFuture] timeIntervalSinceNow] target:self selector:@selector(ignore:) userInfo:nil repeats:YES];
    
    if (!_recvDeviceDataArr) {
        _recvDeviceDataArr = [NSMutableArray array];
    }
    
    while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) {
        FTLog(@"runloop:--%@", _recvDeviceDataArr);
        [self breakUpPacket];
    }
    
    _recvThread = nil;
    _recvDeviceDataArr = nil;
    
    FTLog(@"Recv Data Thread End");
}

+ (void)ignore:(id)_{}

- (void)breakUpPacket{
    @synchronized (self) {
        unsigned short headIndex;
        
        for (NSUInteger i = 0; i < _recvDeviceDataArr.count; i++) {
            NSDictionary *recvDataDic = _recvDeviceDataArr[i];
            NSMutableData *recvData = [recvDataDic objectForKey:@"data"];
            XLDeviceEntity *device = [recvDataDic objectForKey:@"device"];
            if ([device.productID isEqualToString:FTIKCCDeviceProductId]) {
                // [device.productID isEqualToString:FTIKCCDeviceProductId]
                
                //解析网关数据包
                while (recvData.length) {
                    FTIKCCReceiveDataCmd recvCode=0;
                    UInt16 messageId=0;
                    UInt8 temp=0;
                    NSRange subDataRange= recvData.length ? NSMakeRange(0, recvData.length) : NSMakeRange(0, 1);
                    [recvData getBytes:&recvCode range:NSMakeRange(0, 1)];
                    
                    switch (recvCode) {
                        case FTIKCCReceiveDataCmdNotifyNewDevice:
                            if (recvData.length >=38) {
                                [recvData getBytes:&temp range:NSMakeRange(37, 1)];
                                subDataRange = NSMakeRange(0, 1+4+32+1+temp);
                            } else {
                                NSLog(@"网关回复数据: %@",recvData);
                            }
                            break;
                        case 0x07: {
                            subDataRange = NSMakeRange(0, recvData.length);
                            FTLog(@"网关子设备回包，回包控制码%lu",(unsigned long)recvCode);
                            UInt32 subDeviceId=0;
                            if (recvData.length >=5) {
                                 [recvData getBytes:&subDeviceId range:NSMakeRange(1, 4)];
                            }
                            subDeviceId = CFSwapInt32HostToBig(subDeviceId);
#warning the place for deviceModel
                            //暂时屏蔽
                            DeviceModel *deviceModel;// = [FTDATASOURCE.curUser.curFamily getDeviceModelWithDeviceID:[NSString stringWithFormat:@"%zd",subDeviceId]];
                            
                            XLDeviceEntity *childDevice = deviceModel.deviceEntity;
                            if (childDevice) {
                                [self recvData:recvData withDevice:childDevice];
                            }
                            
                            break;
                        }
                        case FTIKCCReceiveDataCmdDeleteDevice:
                        {
                            uint8_t macLench = 0;
                            @try {
                                
                                 [recvData getBytes:&temp range:NSMakeRange(8, 1)];
                                macLench = 1;
                            } @catch (NSException *exception) {
                                FTLog(@"删除子设备数据异常");
                            }
                           
                            subDataRange = NSMakeRange(0, 1+4+2+1+macLench+temp);
                            [recvData getBytes:&messageId range:NSMakeRange(5, 2)];
                            break;
                        }
                            //                        case GatewayRecvCodeSubSub:
                            //                            //tem 标记是否获取subkey成功，不成功不会返回subkey
                            //                            [recvData getBytes:&temp range:NSMakeRange(7, 1)];
                            //                            subDataRange = temp==0?NSMakeRange(0, 1+4+2+1+4):NSMakeRange(0, 1+4+2+1);
                            //                            [recvData getBytes:&messageId range:NSMakeRange(5, 2)];
                            //                            break;
                        case FTIKCCReceiveDataCmdGetSubscribeDeviceList:
                            if (recvData.length <4) {
                                break;
                            }
                            [recvData getBytes:&temp range:NSMakeRange(3, 1)];
                            subDataRange = NSMakeRange(0, 1+2+1+temp*4);
                            [recvData getBytes:&messageId range:NSMakeRange(1, 2)];
                            break;
                        case FTIKCCReceiveDataCmdGetSubscribeDeviceInfo:
                            if (recvData.length <41) {
                                break;
                            }
                            [recvData getBytes:&temp range:NSMakeRange(40, 1)];
                            subDataRange = NSMakeRange(0, 1+4+2+1+32+1+temp+1);
                            [recvData getBytes:&messageId range:NSMakeRange(5, 2)];
                            break;
                        case FTIKCCReceiveDataCmdControlSubDevice:
                            if (recvData.length >=8) {
                                
                                subDataRange = NSMakeRange(0, 1+4+2+1);
                                [recvData getBytes:&messageId range:NSMakeRange(5, 2)];
                            }
                            break;
                        case FTIKCCReceiveDataCmdGetAccesskey:
                            //tem 标记是否获取Accesskey成功，不成功不会返回Accesskey
                            if (recvData.length <8) {
                                break;
                            }
                            [recvData getBytes:&temp range:NSMakeRange(7, 1)];
                            subDataRange = temp==0?NSMakeRange(0, 1+4+2+1+4):NSMakeRange(0, 1+4+2+1);
                            [recvData getBytes:&messageId range:NSMakeRange(5, 2)];
                            break;
                        case FTIKCCReceiveDataCmdSetAccesskey:
                            if (recvData.length < 8) {
                                break;
                            }
                            subDataRange = NSMakeRange(0, 1+4+2+1);
                            [recvData getBytes:&messageId range:NSMakeRange(5, 2)];
                            break;
                        case FTIKCCReceiveDataCmdGetSubKey:
                            if (recvData.length <8) {
                                break;
                            }
                            //tem 标记是否获取subkey成功，不成功不会返回subkey
                            [recvData getBytes:&temp range:NSMakeRange(7, 1)];
                            subDataRange = temp==0?NSMakeRange(0, 1+4+2+1+4):NSMakeRange(
                                                                                         0, 1+4+2+1);
                            [recvData getBytes:&messageId range:NSMakeRange(5, 2)];
                            break;
                        case FTIKCCReceiveDataCmdGetIKCCCurrentStatus:
                            // 获取网关当前状态
//                            subDataRange = NSMakeRange(0, 1+4+2+2+1+1+1);
                            subDataRange = NSMakeRange(0, recvData.length);
                            NSAssert(recvData.length >= subDataRange.length, @"返回数据长度不对...");
                            if (recvData.length < subDataRange.length) {
                                break;
                            }
                            [recvData getBytes:&messageId range:NSMakeRange(5, 2)];
                            break;
                        default:
                            //非上面已知的回包控制码，删除剩余字节的数据，不在继续解析下去
//                            subDataRange = NSMakeRange(0, recvData.length);
                            FTLog(@"注意！出现异常的网关回包，回包控制码%lu不存在",(unsigned long)recvCode);
                            break;
                    }
                    
                    GatewayPacketModel *packet = [self getGatewayPacketModelWithDeviceModel:device andMessageId:messageId];
//                    [[FTIKCCHomeDeviceManager sharedHomeDeviceManager] analysisDataWithControlCode:recvCode andData:[recvData subdataWithRange:subDataRange] andGatewayPacketModel:packet andDeviceEntity:device];
                        //删除已经解析过的数据
                    [recvData replaceBytesInRange:subDataRange withBytes:nil length:0];
                    //删除缓存的数据包
                    [self removeGatewayPacketModel:packet];
                }

            } else {
                // 解析其他设备数据包
                while (recvData.length >= 6) {
                    headIndex = 0;
                    unsigned char recvDataChar[recvData.length];
                    [recvData getBytes:recvDataChar length:recvData.length];
                    
                    //找到包头
                    while (headIndex < recvData.length-1 && ((recvDataChar[headIndex]<<8)+recvDataChar[headIndex+1])!= PACKETHEAD) {
                        headIndex++;
                    }
                    
                    //如果找不到包头
                    if (headIndex >= recvData.length) {
                        recvData.length = 0;
                        FTLog(@"找不到包头");
                        return;
                    }
                    
                    //如果包头不是第一位，把包头前面的数据删掉
                    if (headIndex != 0) {
                        [recvData replaceBytesInRange:NSMakeRange(0, headIndex) withBytes:nil length:0];
                        [recvData getBytes:recvDataChar length:recvData.length];
                    }
                    
                    //如果包长度少于4位，说明还未接收到长度
                    if (recvData.length < 4) {
                        return;
                    }
                    
                    unsigned short dataLen;
                    [recvData getBytes:&dataLen range:NSMakeRange(2, 2)];
                    dataLen = htons(dataLen);
                    
                    //如果包长度少于（4 + dataLen），说明包还未接收完毕
                    if (recvData.length < 4 + dataLen) {
                        FTLog(@"未接收完毕");
                        return;
                    }
                    
                    NSMutableData *data = [NSMutableData dataWithData:[recvData subdataWithRange:NSMakeRange(4, dataLen)]];
                    
                    if (![self validateCheckCodeWithData:[recvData subdataWithRange:NSMakeRange(0, dataLen+4)]]) {
                        [recvData replaceBytesInRange:NSMakeRange(0, 2) withBytes:nil length:0];
                    }else{
                        for (int i = 0; i<data.length-1; i++) {
                            unsigned short number1;
                            [data getBytes:&number1 range:NSMakeRange(i, 1)];
                            //判断有连续的0xF4 , 把其中一个删除
//                            if (number1 == PACKETHEADFIRST) {
//                                unsigned short number2;
//                                [data getBytes:&number2 range:NSMakeRange(i+1, 1)];
//                                if (number2 == PACKETHEADFIRST) {
//                                    [data replaceBytesInRange:NSMakeRange(i, 1) withBytes:nil length:0];
//                                    NNSLog(@"有连续的0xF4 ---> %d",i);
//                                }
//                            }
                        }
                        
                        PacketModel *packetModel = [[PacketModel alloc] initWithPacketData:data];
                        //删除已经解析过的数据
                        [recvData replaceBytesInRange:NSMakeRange(0, 4 + dataLen) withBytes:nil length:0];
                        FTLog(@"%@", packetModel);
                        [self parsingPacketWithRecvPacket:packetModel withDevice:[recvDataDic objectForKey:@"device"]];
                    }
                }
            }
        }
    }
}

//校验码 -- 验证数据是否正确
-(BOOL)validateCheckCodeWithData:(NSData *)data{
    unsigned short checkLen = data.length;
    unsigned char checkData[checkLen];
    [data getBytes:&checkData range:NSMakeRange(0, data.length)];
    unsigned char checkCode = checkData[0];

    for (unsigned short i = 1; i < checkLen-2; i++) {
        checkCode ^= checkData[i];
    }
    
    unsigned char check = checkData[checkLen-1];
    
    return (checkCode==check);
}

//解析数据
- (void)parsingPacketWithRecvPacket:(PacketModel *)recvPacket  withDevice:(XLDeviceEntity *)deviceEntity{
#warning 暂时修改
    DeviceModel *deviceModel;// = [FTDATASOURCE.curUser getDeviceModelWithDeviceEntity:deviceEntity];
    NSMutableString *hexData = [NSMutableString string];
    for (NSUInteger i = 0; i < [recvPacket.payload length]; i++) {
        const char chr = ((const char *)recvPacket.payload.bytes)[i];
        [hexData appendFormat:@"%02X ", (Byte)chr];
    }
    FTLog(@"解析数据到哪里收到数据断点%@",hexData);
    switch (recvPacket.command) {
        case CommandCodeDeviceActiveReportStatus:
        case CommandCodeQueryDeviceStatus: //读取设备的当前状态--joemark
        {   //根据不同设备模型调用各自的方法来解析数据
            if ([deviceModel respondsToSelector:@selector(initWithPayload:)]) {
                [deviceModel initWithPayload:recvPacket.payload]; 
            }
            #warning 暂时修改
//            for (int i = 0; i<FTDATASOURCE.curUser.deviceList.count; i++) {
//                DeviceModel *oldModel = FTDATASOURCE.curUser.deviceList[i];
//                if ([oldModel.deviceEntity.macAddress isEqualToData:deviceModel.deviceEntity.macAddress]) {
//                    [FTDATASOURCE.curUser.deviceList replaceObjectAtIndex:i withObject:oldModel];
//                    break;
//                }
//            }
            if (deviceModel) {
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnReadDeviceStatusNotification object:nil userInfo:@{@"deviceModel":deviceModel}];
            }
        }
            break;
        case CommandSmartCookStatus: //远程云端读取油烟机安卓端的达人秀智能菜谱运行状态
        {
//            if ([deviceModel isKindOfClass:[CookerModel class]]) {
//                CookerModel *model = (CookerModel *)deviceModel;
//                [model initWithSmartCookStatus:recvPacket.payload];
//                for (int i = 0; i<FTDATASOURCE.curUser.deviceList.count; i++) {
//                    DeviceModel *oldModel = FTDATASOURCE.curUser.deviceList[i];
//                    if ([oldModel.deviceEntity.macAddress isEqualToData:deviceModel.deviceEntity.macAddress]) {
//                        [FTDATASOURCE.curUser.deviceList replaceObjectAtIndex:i withObject:oldModel];
//                        break;
//                    }
//                }
                if (deviceModel) {
                    [[NSNotificationCenter defaultCenter]postNotificationName:FTOnReadDeviceStatusNotification object:nil userInfo:@{@"deviceModel":deviceModel}];
                }
//            }
        }
            break;
        /** 消毒柜预约列表相关*/
        case CommandUpdateSterilizerAppointmentList:{
            if (deviceModel) {
                uint8_t flag = 0;
                [recvPacket.payload getBytes:&flag range:NSMakeRange(0, 1)];
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnUpdateDeviceAppointmentListNotification object:nil userInfo:@{@"deviceModel":deviceModel,@"flag":@(flag)}];
            }
        }
            break;
        case CommandQuerySterilizerAppointmentList://预约列表查询
        case CommandUploadSterilizerAppointmentList:{
            if (deviceModel && deviceModel.type == DeviceTypeSterilizer) {
#warning update the 消毒柜
//                SterilizerModel *model = (SterilizerModel *)deviceModel;
//                [model setAppointmentListWithData:recvPacket.payload];
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnReadDeviceAppointmentListNotification object:nil userInfo:@{@"deviceModel":deviceModel,@"data":recvPacket.payload}];
            }
        }
            break;
        /** 消毒柜预约列表相关*/
        case CommandCodeControlDevice: //控制设备
        {
            if (recvPacket.status == 2) {
                if (deviceModel) {
                    [[NSNotificationCenter defaultCenter]postNotificationName:FTOnControlSuccessNotification object:nil userInfo:@{@"deviceModel":deviceModel}];
                    FTLog(@"控制指令发送成功。。。。");
                }
            }
        }
             break;
        case CommandCodeStartLocalCookbook://开始本地菜谱
        {
            if (deviceModel) {
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnControlSuccessNotification object:nil userInfo:@{@"deviceModel":deviceModel}];
                FTLog(@"开始本地菜谱");
            }
        }
             break;
       
        case CommandCodeStartRecordCookbook://开始录制菜谱
        {
            if (deviceModel && recvPacket.payload.length>=13) {
                uint8_t result = 0;
                [recvPacket.payload getBytes:&result range:NSMakeRange(0, 1)];
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnStartRecordCookbookSuccessNotification object:nil userInfo:@{@"deviceModel":deviceModel,@"result":@(result)}];
                FTLog(@"开始录制菜谱");
                NSLog(@"开始录制菜谱========%@",recvPacket.payload);
            }
        }
            break;
        case CommandCodeStopRecordCookbook://结束录制菜谱
        {
            if (deviceModel && recvPacket.payload.length>=14) {
                uint8_t result = 0;
                uint8_t count = 0;
                [recvPacket.payload getBytes:&result range:NSMakeRange(0, 1)];
                [recvPacket.payload getBytes:&count range:NSMakeRange(1, 1)];
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnStopRecordCookbookNotification object:nil userInfo:@{@"deviceModel":deviceModel,@"result":@(result),@"count":@(count)}];
                FTLog(@"结束录制菜谱");
            }
        }
            break;
        case CommandCodeCancelRecordCookbook://取消录制菜谱
        {
            if (deviceModel && recvPacket.payload.length>=13) {
                uint8_t result = 0;
                [recvPacket.payload getBytes:&result range:NSMakeRange(0, 1)];
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnCancelRecordCookbookNotification object:nil userInfo:@{@"deviceModel":deviceModel,@"result":@(result)}];
                FTLog(@"取消录制菜谱");
            }
        }
            break;
        case CommandCodeUploadRecordCookbook://收到上传的菜谱数据
        {
            if (deviceModel && recvPacket.payload.length>14) {
                uint8_t result = 0;
                uint8_t count = 0;
                NSData *data = [recvPacket.payload subdataWithRange:NSMakeRange(14, recvPacket.payload.length-14)];
                [recvPacket.payload getBytes:&result range:NSMakeRange(0, 1)];
                [recvPacket.payload getBytes:&count range:NSMakeRange(13, 1)];
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnUploadRecordCookbookNotification object:nil userInfo:@{@"deviceModel":deviceModel,@"result":@(result),@"count":@(count),@"data":data}];
                FTLog(@"收到上传的菜谱数据");
            }
        }
            break;
            
        case CommandCodeDownloadRecordCookbook:{//开始播放菜谱
            if (deviceModel && recvPacket.payload.length>=13) {
                NSLog(@"开始播放菜谱========%@",recvPacket.payload);
                uint8_t result = 0;
                NSData *data = [recvPacket.payload subdataWithRange:NSMakeRange(1, 12)];
                NSString *str = data.description;
                str = [str stringByReplacingOccurrencesOfString:@"<" withString:@""];
                str = [str stringByReplacingOccurrencesOfString:@">" withString:@""];
                str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
                str = [str uppercaseString];
                [recvPacket.payload getBytes:&result range:NSMakeRange(0, 1)];
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnStartCookbookSuccessNotification object:nil userInfo:@{@"deviceModel":deviceModel,@"result":@(result),@"cookbookId":str}];
                FTLog(@"开始播放菜谱");
            }
        }
            break;
        case CommandCodeStartCookerRecordCookbook:{//开始录制/播放菜谱
            if (deviceModel && recvPacket.payload.length>=13) {
                NSLog(@"开始录制菜谱========%@",recvPacket.payload);
                uint8_t result = 0;
                uint8_t cookerNum = 0;
                NSData *data = [recvPacket.payload subdataWithRange:NSMakeRange(1, 12)];
                NSString *str = data.description;
                str = [str stringByReplacingOccurrencesOfString:@"<" withString:@""];
                str = [str stringByReplacingOccurrencesOfString:@">" withString:@""];
                str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
                str = [str uppercaseString];
                [recvPacket.payload getBytes:&result range:NSMakeRange(0, 1)];
                [recvPacket.payload getBytes:&cookerNum range:NSMakeRange(13, 1)];
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnStartRecordCookbookSuccessNotification object:nil userInfo:@{@"deviceModel":deviceModel,@"result":@(result),@"cookbookId":str,@"cookerNum":@(cookerNum)}];
                FTLog(@"开始录制菜谱");
            }
        }
            break;
        case CommandCodeComfirmCookerAddPrompt:{//添加标记点
            if (deviceModel && recvPacket.payload.length>=13) {
                uint8_t result = 0;
                NSData *data = [recvPacket.payload subdataWithRange:NSMakeRange(0, 12)];
                NSString *str = data.description;
                str = [str stringByReplacingOccurrencesOfString:@"<" withString:@""];
                str = [str stringByReplacingOccurrencesOfString:@">" withString:@""];
                str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
                str = [str uppercaseString];
                [recvPacket.payload getBytes:&result range:NSMakeRange(12, 1)];
                deviceModel.curCookbookID = str;
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnAddPromptSuccessNotification object:nil userInfo:@{@"deviceModel":deviceModel,@"result":@(result),@"cookbookId":str}];
                FTLog(@"添加标记点");
            }
        }
            break;
        case CommandCodeComfirmCookerRecordCookbook:{//确认录制菜谱
            if (deviceModel && recvPacket.payload.length>=12) {
                NSLog(@"确认录制菜谱========%@",recvPacket.payload);
                NSData *data = [recvPacket.payload subdataWithRange:NSMakeRange(0, 12)];
                NSString *str = data.description;
                str = [str stringByReplacingOccurrencesOfString:@"<" withString:@""];
                str = [str stringByReplacingOccurrencesOfString:@">" withString:@""];
                str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
                str = [str uppercaseString];
                [[NSNotificationCenter defaultCenter]postNotificationName:FTOnComfirmCookerRecordCookbookNotification object:nil userInfo:@{@"deviceModel":deviceModel,@"cookbookId":str}];
                FTLog(@"开始播放菜谱");
            }
        }
            break;
        default:
            break;
    }
}
//发送数据--joemark
+ (void)sendPacket:(PacketModel *)packetModel toDevice:(DeviceModel *)deviceModel{
    //    FTLog(@"发送数据--->%@",[packetModel getData]);
    if (deviceModel.isVirtualDevice) {
        return;
    }
    
    FTLog(@"无网关Z1.I流程");
    NSData *data = [packetModel getData];
    Byte byte[data.length];
    memset(byte, 0, data.length);
    [data getBytes:byte length:data.length];
    NSMutableString *string = [NSMutableString string];
    for (int i = 0; i<data.length; i++) {
        [string appendFormat:@"%02X ",byte[i]];
    }
    FTLog(@"发送数据---> 数据%@",string);
    if (deviceModel.deviceEntity.isLANOnline) {
        //        [[XLinkExportObject sharedObject] sendLocalPipeData:deviceModel.deviceEntity andPayload:[packetModel getData]];
        [[XLinkExportObject sharedObject] sendLocalPipeData:deviceModel.deviceEntity andPayload:[packetModel getData] withPriority:PriorityHigh];
    }else{
        [[XLinkExportObject sharedObject] sendPipeData:deviceModel.deviceEntity andPayload:[packetModel getData]];
    }
    
}
///发送网关数据包
- (void)sendGatewayPacketModel:(GatewayPacketModel *)model{
    if (model.deviceModel.isVirtualDevice) {
        return;
    }
    
    //缓存发送的网关数据(有效的网关数据，存在messageID)
    if (model.messageId) {
        if (model.deviceModel.mac) { // 包含mac地址才进行发送
            if (![self.sendDeviceDataArrDict.allKeys containsObject:model.deviceModel.mac]) {
                [self.sendDeviceDataArrDict setObject:@[] forKey:model.deviceModel.mac];
            }
            NSMutableArray *tem = [NSMutableArray arrayWithArray:self.sendDeviceDataArrDict[model.deviceModel.mac]];
            [tem addObject:model];
            [self.sendDeviceDataArrDict setObject:tem forKey:model.deviceModel.mac];
        }
    }
    
    NSData *data = model.sendData;
    Byte byte[data.length];
    memset(byte, 0, data.length);
    [data getBytes:byte length:data.length];
    NSMutableString *string = [NSMutableString string];
    for (int i = 0; i<data.length; i++) {
        [string appendFormat:@"%02X ",byte[i]];
    }
    FTLog(@"发送数据---> 数据%@",string);
    
    if (model.deviceModel.deviceEntity.isLANOnline) {
        [[XLinkExportObject sharedObject] sendLocalPipeData:model.deviceModel.deviceEntity andPayload:data withPriority:PriorityLow];
    }else{
        [[XLinkExportObject sharedObject] sendPipeData:model.deviceModel.deviceEntity andPayload:data];
    }
}

- (NSMutableDictionary *)sendDeviceDataArrDict{
    if (!_sendDeviceDataArrDict) {
        _sendDeviceDataArrDict = [NSMutableDictionary dictionary];
    }
    return _sendDeviceDataArrDict;
}
- (GatewayPacketModel *)getGatewayPacketModelWithDeviceModel:(XLDeviceEntity *)device andMessageId:(UInt32)messageId{
    GatewayPacketModel *tem = nil;
    NSArray *packets = self.sendDeviceDataArrDict[device.getMacAddressSimple];
    for (GatewayPacketModel *packet in packets) {
        if (packet.messageId == messageId) {
            tem = packet;
            break;
        }
    }
    return tem;
}
- (void)removeGatewayPacketModel:(GatewayPacketModel *)packetModel{
    if (packetModel) {
        NSMutableArray *tem = [NSMutableArray arrayWithArray:self.sendDeviceDataArrDict[packetModel.deviceModel.mac]];
        [tem removeObject:packetModel];
        [self.sendDeviceDataArrDict setObject:tem forKey:packetModel.deviceModel.mac];
    }
}
@end
